package com.wry.juc;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <h1>  </h1>
 *
 * @author wry
 * @since 2025.04.01
 */
public class BlockingQueueTest {


    public static void main(String[] args) {
        MyBLQ<String> myBLQ = new MyBLQ<>(10);
        CompletableFuture.runAsync(() -> {
            while (true) {
                String take = myBLQ.take();
                System.out.println("取出元素-"+take);
                try { Thread.sleep(1500L); } catch (InterruptedException e) { e.printStackTrace();}
            }
        });
        for (int i = 0; i < 1000; i++) {
            System.out.println("放入元素-"+"i-"+i);
            myBLQ.add("i-"+i);
            try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace();}
        }
        try { Thread.sleep(500000L); } catch (InterruptedException e) { e.printStackTrace();}
    }



    static class MyBLQ<E> {
        private Queue<E> queue;
        private Integer capacity;
        private ReentrantLock lock;
        private Condition fullCondition; // 队列满
        private Condition emptyCondition; // 队列空

        public MyBLQ(Integer capacity) {
            this.queue = new LinkedList<E>();
            this.capacity = capacity;
            this.lock = new ReentrantLock();
            this.fullCondition = lock.newCondition();
            this.emptyCondition = lock.newCondition();
        }

        public void add(E e) {
            try {
                lock.lock();

                while (queue.size() == capacity) {
                    // 队满进入阻塞
                    System.out.println("队满进入阻塞");
                    fullCondition.await();
                }
                queue.add(e);
                emptyCondition.signal();
            }catch (Exception exception) {
                exception.printStackTrace();
            }finally {
                lock.unlock();
            }
        }

        public E take() {
            try {
                lock.lock();

                while (queue.size() == 0) {
                    // 队列空进入阻塞
                    System.out.println("队空进入阻塞");
                    emptyCondition.await();
                }
                E poll = queue.poll();
                fullCondition.signal();
                return poll;
            }catch (Exception exception) {
                exception.printStackTrace();
            }finally {
                lock.unlock();
            }
            return null;
        }
    }
}
